﻿using MvcApplication.App_Start;
using MvcApplication.Entity;
using MvcApplication.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.Practices.Unity;
using System.Web.Security;
using System.Web.Caching;
using System.Net;


namespace MvcApplication.Common
{
    public static class UserSession
    {
        private static readonly string CookieName = "49548DB7C1E9D4D846";
        private static readonly string SecretKey = "49548DB7AC1E9D4D845";
        public static UserInfoDto User
        {
            get
            {
                string userID = HttpContext.Current.User.Identity.Name;
                if (string.IsNullOrEmpty(userID) && AppSettings.IsVirrtualHosting)
                {
                    userID = GetIdentity();
                }

                var user = (UserInfoDto)HttpRuntime.Cache.Get(userID);
                if (user == null && !string.IsNullOrEmpty(userID))
                {
                    var userSessionService = UnityConfig.GetConfiguredContainer().Resolve<IUserSessionService>();
                    user = userSessionService.NewDtoForCache(userID);

                    if (user == null)
                    {
                        if (AppSettings.IsVirrtualHosting) ClearIdentity();
                        FormsAuthentication.SignOut();
                    }
                    else
                    {
                        HttpContext.Current.Cache.Add(userID,
                            user,
                            null,
                            Cache.NoAbsoluteExpiration,
                            new TimeSpan(0, 30, 0),
                            CacheItemPriority.Normal, null);

                        if (AppSettings.IsVirrtualHosting) SetIdentity(userID);
                    }
                }
                return user;
            }
        }

        public static bool Login(string email, string password)
        {
            var service = UnityConfig.GetConfiguredContainer().Resolve<IUserSessionService>();
            var user = service.Login(email, password);
            if (user == null) return false;


            FormsAuthentication.SetAuthCookie(user.ID.ToString(), true);
            HttpContext.Current.Cache.Add(user.ID.ToString(),
                user,
                null,
                Cache.NoAbsoluteExpiration,
                new TimeSpan(0, 30, 0),
                CacheItemPriority.Normal, null);

            if (AppSettings.IsVirrtualHosting) SetIdentity(user.ID.ToString());
            return true;
        }

        public static void LogOut()
        {
            HttpContext.Current.Cache.Remove(HttpContext.Current.User.Identity.Name);
            FormsAuthentication.SignOut();
            if (AppSettings.IsVirrtualHosting) ClearIdentity();
        }

        #region

        static void SetIdentity(string userID)
        {
            var cookie = HttpContext.Current.Response.Cookies[CookieName];
            if (cookie != null && cookie.Expires > DateTime.Now) return;

            var date = DateTime.Now;
            var datetime = date.Ticks;
            var md5 = (userID + SecretKey + datetime).MD5();

            cookie = new HttpCookie(CookieName);
            cookie.Expires = date.AddDays(1);
            cookie.Values.Add("USERID", userID);
            cookie.Values.Add("DATETIME", datetime.ToString());
            cookie.Values.Add("MD5", md5);
            HttpContext.Current.Response.Cookies.Add(cookie);
        }

        static string GetIdentity()
        {
            var cookie = HttpContext.Current.Request.Cookies.Get(CookieName);
            if (cookie == null || cookie.Value == null)
                return string.Empty;

            var datetime = cookie.Values["DATETIME"];
            var md5 = cookie.Values["MD5"];
            var userID = cookie.Values["USERID"];

            if ((userID + SecretKey + datetime).MD5() != md5) // 被篡改了
                return string.Empty;

            if (long.Parse(datetime) < DateTime.Now.AddDays(-1).Ticks) return string.Empty;
            FormsAuthentication.SetAuthCookie(userID, true);
            return userID;
        }

        static void ClearIdentity()
        {
            var cookie = HttpContext.Current.Response.Cookies[CookieName];
            if (cookie == null) return;
            cookie.Expires = DateTime.Now.AddDays(-1);
        }
        #endregion
    }
}